package com.wlc.service.impl;

import com.wlc.mapper.MenuMapper;
import com.wlc.pojo.Menu;
import com.wlc.pojo.PageResult;
import com.wlc.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MenuServiceImpl implements MenuService {

    @Override
    public PageResult<Menu> findMenuList(String name, Integer type, Integer page, Integer size) {
        log.info("查询菜单列表分页: name={}, type={}, page={}, size={}",
                name, type, page, size);

        if (page == null || page < 1) page = 1;
        if (size == null || size < 1) size = 10;

        Long total = menuMapper.selectMenuCount(name, type);
        List<Menu> menus = menuMapper.selectMenuList(name, type, (page - 1) * size, size);

        return new PageResult<>(total, menus);
    }

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public Menu findById(Long id) {
        log.info("根据ID查询菜单: {}", id);
        return menuMapper.selectById(id);
    }

    @Override
    public List<Menu> findAll() {
        log.info("查询所有菜单");
        return menuMapper.selectAll();
    }

    @Override
    public List<Menu> findTree() {
        log.info("查询菜单树形结构");
        List<Menu> allMenus = menuMapper.selectTree();
        return buildMenuTree(allMenus, 0L);
    }

    @Override
    public List<Menu> findByType(Integer type) {
        log.info("根据类型查询菜单: type={}", type);
        return menuMapper.selectByType(type);
    }

    @Override
    public List<Menu> findUserMenuTree(Long userId) {
        log.info("查询用户菜单树: userId={}", userId);
        List<Menu> userMenus = menuMapper.selectByUserId(userId);
        return buildMenuTree(userMenus, 0L);
    }

    @Override
    public List<String> findUserPerms(Long userId) {
        log.info("查询用户权限: userId={}", userId);
        return menuMapper.selectPermsByUserId(userId);
    }

    /**
     * 构建菜单树形结构
     */
    private List<Menu> buildMenuTree(List<Menu> menus, Long parentId) {
        return menus.stream()
                .filter(menu -> parentId.equals(menu.getParentId()))
                .peek(menu -> menu.setChildren(buildMenuTree(menus, menu.getId())))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void save(Menu menu) {
        log.info("新增菜单: {}", menu.getName());

        // 校验权限标识是否唯一（按钮类型）
        if (menu.getType() == 3 && menu.getPerms() != null) {
            List<Menu> existingMenus = menuMapper.selectAll();
            boolean exists = existingMenus.stream()
                    .anyMatch(m -> menu.getPerms().equals(m.getPerms()) && m.getType() == 3);
            if (exists) {
                throw new RuntimeException("权限标识已存在");
            }
        }

        // 设置默认值
        if (menu.getIsVisible() == null) {
            menu.setIsVisible(1);
        }
        if (menu.getSort() == null) {
            menu.setSort(0);
        }
        // 移除 isDeleted 设置
        menu.setCreateTime(LocalDateTime.now());
        menu.setUpdateTime(LocalDateTime.now());

        if (menu.getParentId() == null) {
            menu.setParentId(0L);
        }

        int result = menuMapper.insert(menu);
        if (result <= 0) {
            throw new RuntimeException("新增菜单失败");
        }
        log.info("新增菜单成功: {}", menu.getName());
    }

    @Override
    @Transactional
    public void update(Menu menu) {
        log.info("更新菜单: {}", menu.getId());

        Menu existingMenu = menuMapper.selectById(menu.getId());
        if (existingMenu == null) {
            throw new RuntimeException("菜单不存在");
        }

        // 防止设置自己为父菜单
        if (menu.getId().equals(menu.getParentId())) {
            throw new RuntimeException("不能设置自己为父菜单");
        }

        // 校验权限标识是否唯一（按钮类型）
        if (menu.getType() != null && menu.getType() == 3 && menu.getPerms() != null) {
            List<Menu> existingMenus = menuMapper.selectAll();
            boolean exists = existingMenus.stream()
                    .anyMatch(m -> menu.getPerms().equals(m.getPerms())
                            && m.getType() == 3
                            && !m.getId().equals(menu.getId()));
            if (exists) {
                throw new RuntimeException("权限标识已存在");
            }
        }

        menu.setUpdateTime(LocalDateTime.now());
        int result = menuMapper.update(menu);
        if (result <= 0) {
            throw new RuntimeException("更新菜单失败");
        }
        log.info("更新菜单成功: {}", menu.getId());
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        log.info("删除菜单: {}", id);

        Menu menu = menuMapper.selectById(id);
        if (menu == null) {
            throw new RuntimeException("菜单不存在");
        }

        // 检查是否有子菜单
        if (menuMapper.existsChildren(id)) {
            throw new RuntimeException("该菜单下存在子菜单，无法删除");
        }

        // 改为物理删除
        int result = menuMapper.deleteById(id);
        if (result <= 0) {
            throw new RuntimeException("删除菜单失败");
        }
        log.info("删除菜单成功: {}", id);
    }
}